home *** CD-ROM | disk | FTP | other *** search
- /* Code for demo program */
-
- #include <SANE.h>
- #include "Demo.h"
- #include "EqnCompiler.h"
-
- /* Global Variables */
- Handle eqnCode; /* handle to block of code */
- char **eqnText; /* handle to eqn text */
- extended (*eqnFn)(); /* func ptr to eqn code */
- extended coeff[5]; /* array of coefficients */
- extended minX, maxX, minY, maxY; /* plot range */
- DialogPtr eqnDialog; /* dialog pointer */
- CursHandle iBeam, watch;
-
- main()
- {
- Handle userItemH;
- int i, type, itemHit, error, index;
- Rect rect;
-
- InitStuff();
- eqnDialog = GetNewDialog(300, NULL, (WindowPtr) -1); /* get dialog */
- GetDItem(eqnDialog, FUNCTION, &type, &eqnText, &rect); /* get handle to eqn text */
- GetDItem(eqnDialog, FRAME, &type, &userItemH, &rect); /* get user item (plot frame) */
- SetDItem(eqnDialog, FRAME, type, FramePlot, &rect); /* install user item */
- /* centre window on screen */
- MoveWindow(eqnDialog, (screenBits.bounds.right-screenBits.bounds.left - 490)/2, 45, true);
- ShowWindow(eqnDialog);
- SetPort(eqnDialog);
-
- do {
- ModalDialog(DialogFilter, &itemHit);
- if (itemHit == COMPILE) { /* compile eqn */
- /* Code block should be unlocked and */
- /* eqn text buffer should be locked. */
- HUnlock(eqnCode);
- HLock(eqnText);
- index = 0; /* parse text from start */
- error = CompileEqn(*eqnText, GetHandleSize(eqnText), &index, eqnCode);
- if (error) {
- /* position of error is in index */
- SelIText (eqnDialog, FUNCTION, index, index);
- /* put up alert to explain error */
- SyntaxErr(error);
- eqnFn = NULL; /* null function ptr */
- } else {
- SelIText (eqnDialog, FUNCTION, 0, 0);
- /* compiled OK, lock code block and */
- /* dereference to get address of func */
- HLock(eqnCode);
- eqnFn = (void *) *eqnCode;
- }
- } else if (itemHit == PLOT) { /* plot eqn */
- /* update coefficients array */
- for (i=0; i<5; i++)
- coeff[i] = GetEditField(COEFF_A + i);
- /* update plot range */
- minX = GetEditField(MIN_X);
- maxX = GetEditField(MAX_X);
- minY = GetEditField(MIN_Y);
- maxY = GetEditField(MAX_Y);
- PlotEqn();
- }
- } while (itemHit != QUIT);
-
- DisposDialog(eqnDialog); /* tidy up & leave */
- HUnlock(eqnCode);
- }
-
- void InitStuff(void)
- {
- MaxApplZone();
- InitGraf(&thePort);
- InitFonts();
- FlushEvents(everyEvent, 0);
- InitWindows();
- TEInit();
- InitDialogs(NULL);
-
- eqnCode = NewHandle(0); /* allocate memory */
- if (MemError()) ExitToShell();
- eqnFn = NULL;
- iBeam = GetCursor(iBeamCursor);
- watch = GetCursor(watchCursor);
- InitCursor();
- }
-
- /* Plot the equation */
- void PlotEqn(void)
- {
- extended x, y, vert;
- int hPos=0, lastvPos, vPos;
- char skip=2;
- Rect plotRect, bigRect;
-
- if (!eqnFn) return; /* invalid function */
- if ((minX >= maxX) || (minY >= maxY))
- return; /* invalid plot range */
- SetRect(&plotRect, 170, 59, 470, 230);
- EraseRect(&plotRect); /* clear plot area */
- ClipRect(&plotRect); /* new clip region */
- SetCursor(*watch);
-
- do {
- /* calculate x */
- x = minX + (maxX - minX)*hPos/300.0;
- y = (*eqnFn)(x, coeff); /* calculate y */
- if (fabs(classextended(y)) < 2)
- skip = 2; /* y is a NAN */
- else { /* get new Y screen coord */
- lastvPos = vPos; /* save last Y coord */
- vert = rint(170*(maxY-y)/(maxY-minY));
- /* pin extreme values to window's edge */
- if (vert+59>eqnDialog->portRect.bottom)
- vPos = eqnDialog->portRect.bottom-59;
- else if (vert+59<eqnDialog->portRect.top)
- vPos = eqnDialog->portRect.top-59;
- else vPos = vert;
- if (y >= minY && y <= maxY) {
- /* y is in range */
- if (skip < 2) /* last y was not NAN */
- LineTo(170+hPos, 59+vPos);
- else MoveTo(170+hPos, 59+vPos);
- skip = 0;
- } else { /* y is out of range */
- if (!skip) /* last point was in range */
- LineTo(170+hPos, 59+vPos);
- else MoveTo(170+hPos, 59+vPos);
- skip = 1;
- }
- }
- } while ((hPos += 2) <= 300);
-
- SetRect(&bigRect, -32767, -32767, 32767, 32767);
- ClipRect(&bigRect); /* reset clip rect */
- }
-
- /* put up alert explaining the syntax error */
- void SyntaxErr(int error)
- {
- AlertTHndl templateH;
- Str255 str;
-
- InitCursor();
- /* read alert into memory, make unpurgeable */
- CouldAlert(301);
- /* get handle to template */
- templateH = (AlertTHndl) GetResource('ALRT', 301);
- /* centre the alert box on the screen */
- (*templateH)->boundsRect.left = (screenBits.bounds.right-screenBits.bounds.left - 260)/2;
- (*templateH)->boundsRect.right = (*templateH)->boundsRect.left + 260;
- GetIndString(str, 128, error); /* get message */
- ParamText(str, "\p", "\p", "\p");
- NoteAlert(301, NULL);
- FreeAlert(301); /* mark alert purgeable again */
- }
-
- /* get value from a dialog TE field */
- extended GetEditField(int itemNo)
- {
- Str255 str;
- int type;
- extended value;
- Handle edText;
- Rect rect;
-
- /* get handle to editable text */
- GetDItem(eqnDialog, itemNo, &type, &edText, &rect);
- GetIText(edText, str); /* retrieve text */
- if (!str[0]) return 0; /* str is NULL */
- value = str2num(str);
- if (fabs(classextended(value)) < 2)
- return 0; /* value is a NAN */
- return value;
- }
-
- pascal Boolean DialogFilter(DialogPtr theDialog, EventRecord *theEvent, int *itemHit)
- {
- Point mousePt;
- int item, type;
- char c;
- Rect rect;
- Handle hand;
- TEHandle dialogTE;
-
- if (theEvent->what == keyDown) {
- /* disable clear, enter keys in all fields */
- c = theEvent->message & charCodeMask;
- if (c == CLEAR_KEY || c == ENTER)
- return true;
- if (((DialogPeek) theDialog)->editField + 1 == FUNCTION) {
- /* current edit field is function */
- if (c == TAB) {
- /* override default tab behaviour */
- dialogTE = ((DialogPeek) theDialog)->textH;
- TEKey(TAB, dialogTE);
- return true;
- }
- } else if (c == RETURN)
- /* disable return in other fields */
- return true;
- }
-
- /* set cursor as appropriate */
- GetMouse(&mousePt);
- item = 1 + FindDItem(theDialog, mousePt);
- if (item) {
- GetDItem(theDialog, item, &type, &hand, &rect);
- if (type == editText) SetCursor(*iBeam);
- else InitCursor();
- } else InitCursor();
-
- return false;
- }
-
- /* draw plot frame */
- pascal void FramePlot(DialogPtr theDialog, short item)
- {
- Rect frameRect;
-
- SetRect(&frameRect, 168, 57, 472, 232);
- FrameRect(&frameRect);
- }
-
-